#pragma once

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


// 函数宏
#define debug(format, ...) \
Logger::instance()->log(Logger::DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__)

#define info(format, ...) \
Logger::instance()->log(Logger::INFO, __FILE__, __LINE__, format, ##__VA_ARGS__)

#define warn(format, ...) \
Logger::instance()->log(Logger::WARN, __FILE__, __LINE__, format, ##__VA_ARGS__)

#define error(format, ...) \
Logger::instance()->log(Logger::ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__)

#define fatal(format, ...) \
Logger::instance()->log(Logger::FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__)

class Logger
{
public:
    enum Level
    {
        DEBUG = 0,
        INFO,
        WARN,
        ERROR,
        FATAL,
        LEVEL_COUNT
    };
    static Logger *instance();
    void open(const string &filename);
    void close();
    void log(Level level, const char *file, int line, const char *format, ...);
    void level(Level lever);
    void max(int bytes);
    void isTermial(const bool value);

private:
    Logger();
    ~Logger();
    void rotate();

private:
    string m_filename;
    ofstream m_fout;
    static const char *s_level[LEVEL_COUNT];
    Level m_lever; // 日志级别
    int m_max;     // 最大日志长度
    int m_len;     // 当前日志长度
    bool m_isTermial = true;

    static Logger *m_instance; //单列模式
};
